package com.njupt.service;

import java.io.IOException;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import net.sf.json.JsonConfig;
import net.sf.json.util.PropertyFilter;

import org.apache.commons.beanutils.BeanUtilsBean;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.njupt.blog.Constants;
import com.njupt.user.model.User;
import com.njupt.utils.RequestUtils;
import com.njupt.utils.DateConverter;
import com.njupt.service.UniversalManager;

public class BaseAction extends ActionSupport
{
	private static final long serialVersionUID = 1L;
	protected static final Log log = LogFactory.getLog(BaseAction.class);
	protected static JsonConfig conf = new JsonConfig();
	protected static Set defaultExclude = new HashSet();
	static{
		defaultExclude.add("pageNo");
		defaultExclude.add("pageSize");
		ConvertUtils.register(new DateConverter(), Date.class);
		ConvertUtils.register(new DateConverter(), String.class);
		conf.setJsonPropertyFilter(new PropertyFilter(){
		    public boolean apply(Object source, String name, Object value) {
		    	if(name.indexOf("CGLIB$")>0 || name.equals("hibernateLazyInitializer")){
					return true;
		    	}
		    	return false;
		    }
		});
	}
	public UniversalManager manager;
	public static final String EDITFORM = "editForm";
	public static final String LIST = "list";
	public static final String VIEW = "view";
	protected int pageNo = 1;
	protected int pageSize = 15;
	//分页的时候常用这个来记录查询条件。
	protected String conditionStr;
	public int getPageNo() {
		return pageNo;
	}

	public void setPageNo(Integer pageNo) {
		if(pageNo != null)
		this.pageNo = pageNo;
	}

	public int getPageSize() {
		return pageSize;
	}

	public void setPageSize(Integer pageSize) {
		if(pageSize != null)
		this.pageSize = pageSize;
	}
	/**
	 * 按照指定的类型从request对象中获取值。
	 * 
	 * @param paramName
	 * @param type
	 * @return
	 */
	public Object getParameter(String paramName,Class type){
		return RequestUtils.getObject(getRequest(),paramName,type);
	}
	/**
	 * 将String或则String[]类型的值转换为指定类型的值。
	 * 
	 * @param v 只能是String或则String[]。
	 * @param type
	 * @return
	 */
	public Object convert(Object v,Class type){
		if(v == null)return null;
		if("".equals(v)){//如果v为空字符串，并且需要转化为的不是String或String[]，那么就返回null。
			if(type==String.class)return v;
			if(type == String[].class)return new String[]{""};
			return null;
		}
		BeanUtilsBean utils = BeanUtilsBean.getInstance();
		if(type.isArray()){
			String[] vs = null;
			if(!(v instanceof String[])){
				vs = new String[]{(String)v};
			}else{
				vs = (String[])v;
			}
			return utils.getConvertUtils().convert(vs, type);
		}
		return utils.getConvertUtils().convert((String)v, type);
	}
	/**
	 * 获取放在app.properties里的配置信息。
	 * 
	 * @param proName
	 * @return
	 */
	public String getAppConfig(String proName){
		Properties applicationProperties = (Properties) ServletActionContext.getServletContext().getAttribute("appConf");
		if(applicationProperties == null){
			log.warn("no appConf in application.");
			return null;
		}
		return applicationProperties.getProperty(proName);
	}
	/**
	 * 拼请求路径(仅适于存储查询条件)。
	 * 
	 * @param replaceMap
	 * @return
	 */
	protected String composeSearchQueryString(Map replaceMap,Set exclude){
		HttpServletRequest request = getRequest();
		String url = "";
		Map m = RequestUtils.getParameterMap(request);
		if(replaceMap != null)
			m.putAll(replaceMap);
		Iterator keySet = m.keySet().iterator();
		int j = 0;
		for (;keySet.hasNext();) {
			Object key = keySet.next();
			if(exclude != null && exclude.contains(key))continue;
			if(key.toString().startsWith("method:"))continue;
			Object[] values = null;
			Object value = m.get(key);
			if(value instanceof String){
				values = new Object[]{value};
			}else{
				values = (Object[])value;
			}
			for (int i = 0; i < values.length; i++) {
				if(j != 0)url += "&";
				j++;
				url += key + "=" + values[i];
			}
		}
		return url;
	}
	protected void responseWrite(String str){
		getResponse().setCharacterEncoding("utf-8");
		getResponse().setContentType("text/html;charset=utf-8");
		try {
			getResponse().getWriter().write(str);
		} catch (IOException e) {
			throw new RuntimeException(e.getMessage(),e);
		}
	}
	protected String composeSearchQueryString(Map replaceMap){
		return composeSearchQueryString(replaceMap, null);
	}
	public String getConditionStr() {
		return conditionStr;
	}

	public void setConditionStr(String conditionStr) {
		this.conditionStr = conditionStr;
	}
	
	protected void setRequestAttr(String key,Object value){
		Map requestMap = (Map)ActionContext.getContext().get("request");
		requestMap.put(key, value);
	}

	/**
	 * 分页的时候需要过滤掉pageNo,pageSize。
	 * @return
	 */
	protected  String composePaginationSearchQueryString(){
		return composeSearchQueryString(null,defaultExclude);
	}
	protected String composeSearchQueryString(){
		return composeSearchQueryString(null, null);
	}
	public UniversalManager getManager()
	{
		return manager;
	}
	public void setManager(UniversalManager manager)
	{
		this.manager = manager;
	}
	public String getCurrentUsername(){
		return (String)ServletActionContext.getRequest().getSession().getAttribute("currentUsername");
	}
	public User getCurrentUser(){
		return (User) ServletActionContext.getRequest().getSession().getAttribute(Constants.SECURITY_CONTEXT_KEY);
	}
	 /**
     * Convenience method to get the request
     * @return current request
     */
    protected HttpServletRequest getRequest() {
        return ServletActionContext.getRequest();
    }

    /**
     * Convenience method to get the response
     * @return current response
     */
    protected HttpServletResponse getResponse() {
        return ServletActionContext.getResponse();
    }

    /**
     * Convenience method to get the session. This will create a session if one doesn't exist.
     * @return the session from the request (request.getSession()).
     */
    protected HttpSession getSession() {
        return getRequest().getSession();
    }
    /**
     * Convenience method to get the application.
     * @return ServletContext
     */
    protected ServletContext getServletContext(){
    	return  ServletActionContext.getServletContext();
    }

}
